package com.teckteam.ptvsystem.model;

import java.util.HashMap;

import com.teckteam.ptvsystem.model.facade.PTVConstants;

/**
 * Objects of this class represent as a storage object holding both the
 * departure time instance which may be shared among line timetables, as well
 * as their corresponding destination.
 * 
 */
public class DepartureTime implements Comparable
{
   private AbstractStop destinationStop;
   private int          hours, minutes;
   private String       isAmPm;
   private static HashMap<String, DepartureTime> instances;
   
   /**
    * Gets its corresponding DepartureTime instance based on parameters.
    * If it doesn't exist it'll create it.
    * 
    * @param hours
    * @param minutes
    * @param ampmPut
    * @return
    */
   public static DepartureTime getInstance(int hours, int minutes, String ampmPut)
   {
      String input = String.format("%d:%02d %s", hours, minutes, ampmPut);
      DepartureTime d;
      
      if (instances==null)
      {
         instances = new HashMap<String, DepartureTime>();
         instances.put(PTVConstants.BLANK_TIME, new DepartureTime());
      }
      
      if ((d = instances.get(input))==null)
      {   
         d = new DepartureTime(hours, minutes, ampmPut);
         instances.put(input, d);
      }
      return d;
   }
   
   /**
    * Gets the blank DepartureTime instance.  If none exist, creates it.
    */
   public static DepartureTime getInstance()
   {
      if(instances==null)
      {
         instances = new HashMap<String, DepartureTime>();
         instances.put(PTVConstants.BLANK_TIME, new DepartureTime());
      }
      
      return instances.get(PTVConstants.BLANK_TIME);
   }
   
   private DepartureTime()
   {
      this.hours = -1;
      this.minutes = -1;
      this.isAmPm = ".";
   }
   
   private DepartureTime(int hours, int minutes, String ampmPut)
   {
      this.hours = hours;
      this.minutes = minutes;
      this.isAmPm = ampmPut;
      
   }
   
   /**
    * For ArrayList to String array conversion
    */
   public String toString() {
      if(hours<0 || minutes<0 || isAmPm.charAt(0)=='.')
         return PTVConstants.BLANK_TIME;
         
      return String.format("%d:%02d %s", hours, minutes, isAmPm);
   }
   
   /**
    * Comparator for DepartureTime objects. Returns the difference in minutes where
    * a negative value indicates the target reference object is earlier.  
    */
   public int compareTo(Object o)
   {
      if(!(o instanceof DepartureTime))
         return PTVConstants.FAILED_COMPARE;
      
      int input[] = ((DepartureTime)o).toArray(),
          first = hours*60 + minutes,
          second = input[0]*60 + minutes,
          result = second - first;
      
      //Return closer result with respect to clock.
      if (result < (-12*60))
         result += 24*60;
      else if (result > (12*60))
         result -= 24*60;
      
      return result;
   }
   
   /**
    * Returns 2-element int array representation of DepartureTime, in 24-hour time.
    * @return arr
    */
   private int[] toArray()
   {
      int arr[] = {
            hours,
            minutes
      };
      if(isAmPm.compareTo("pm")==0 && hours > 12)
         arr[0] += 12;
      else if(isAmPm.compareTo("am")==0 && hours == 12)
         arr[0] = 0;
      
      return arr;
   }
}
